/**
 * ADODB implementation of haxe.db.ResultSet
 * 
 * Question: How to initialize a for-loop so that we can call rs.moveFirst() ???
 * 
 * @author Cref
 */

package js.db;

import js.db.ResultSet;
import activex.adodb.RecordSet;

class ADOResultSet implements ResultSet {

	public var length(getLength,null) : Int;
	public var nfields(getNFields,null) : Int;
	var rs : RecordSet;

	public function new(rs:RecordSet) {
		this.rs = rs;
	}
	
	//TODO: should return rowsAffected for INSERT, UPDATE or DELETE
	private function getLength() {
		return rs.recordCount;
	}

	private function getNFields() {
		return rs.fields.count;
	}

	public function hasNext() {
		return !rs.eof;
	}

	//TODO: optimize
	public function next() : Dynamic {
		var r = { };
		//fixes ADODB dates for JScript
		//f.name.toLowerCase() ?
		for (f in rs.fields) {
			//TODO: make Date type a connection property (Access=7, SQLite/MySQL/SQLServer DATE=133, DATETIME=135 ...)
			//trace(f.name+': '+f.type+': '+f.value);
			Reflect.setField(r, f.name, fixDate(f));
		}
		rs.moveNext();
		return r;
	}
	
	private static function fixDate(f:activex.adodb.Field):Dynamic {
		return (f.type == 7 || f.type == 133 || f.type == 135) && f.value != null?untyped __js__('new Date')(f.value):f.value;
	}
	
	public function results() : List<Dynamic> {
		var l = new List();
		for (row in this) l.add(row);
		return l;
	}
	
	public function getFieldsNames() : Null<Array<String>> {
		var r = [];
		for (f in rs.fields) r.push(f.name);
		return r;
	}

	//ADODB already uses the correct datatypes for String, Int and Float so we don't do any conversion
	public function getResult( n : Int ) : String return ''+fixDate(rs.fields.item(n))
	public function getIntResult( n : Int ) : Int return rs.fields.item(n).value
	public function getFloatResult( n : Int ) : Float return rs.fields.item(n).value
}